package com.google.android.location.content;

import static com.google.android.location.content.Constants.TAG;

import com.google.android.locatiom.maps.myroutes.R;
import com.google.android.location.content.libcontent.RoutesColumns;
import com.google.android.location.content.service.ConnectionServiceManager;
import com.google.android.location.content.service.ControlRecordingService;
import com.google.android.location.content.service.ServiceControl;
import com.google.android.location.content.utilities.StringsProfiler;
import com.google.android.location.content.utilities.UnitConversions;

import android.app.ListActivity;
import android.content.ContentUris;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.ContextMenu;
import android.view.MenuItem;
import android.view.SubMenu;
import android.view.View;
import android.view.Window;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.View.OnCreateContextMenuListener;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.SimpleCursorAdapter;
import android.widget.TextView;

public class RouteList extends ListActivity implements
		SharedPreferences.OnSharedPreferenceChangeListener,
		View.OnClickListener {

	private int contextPosition = -1;
	private long routeId = -1;
	private ListView listView = null;
	private boolean metricUnits = true;

	private Cursor routesCursor = null;

	/**
	 * The id of the currently recording route.
	 */
	private long recordingRouteId = -1;

	private final OnCreateContextMenuListener contextMenuListener = new OnCreateContextMenuListener() {
		@Override
		public void onCreateContextMenu(ContextMenu menu, View v,
				ContextMenuInfo menuInfo) {
			menu.setHeaderTitle(R.string.route_list_context_menu_title);
			AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) menuInfo;
			contextPosition = info.position;
			routeId = RouteList.this.listView.getAdapter().getItemId(
					contextPosition);
			menu.add(0, Constants.MENU_SHOW, 0, R.string.route_list_show_on_map);
			menu.add(0, Constants.MENU_EDIT, 0, R.string.route_list_edit_route);
			menu.add(0, Constants.MENU_DELETE, 0,
					R.string.route_list_delete_route);
		}

	};

	private final Runnable serviceBindingChanged = new Runnable() {
		@Override
		public void run() {
			updateButtonsEnabled();
		}
	};

	private ConnectionServiceManager serviceConnection;
	private SharedPreferences preferences;

	@Override
	public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,
			String key) {
		if (key == null) {
			return;
		}
		if (key.equals(getString(R.string.metric_units_key))) {
			metricUnits = sharedPreferences.getBoolean(
					getString(R.string.metric_units_key), true);
			if (routesCursor != null && !routesCursor.isClosed()) {
				routesCursor.requery();
			}
		}
		if (key.equals(getString(R.string.recording_route_key))) {
			recordingRouteId = sharedPreferences.getLong(
					getString(R.string.recording_route_key), -1);
		}
	}

	@Override
	protected void onListItemClick(ListView l, View v, int position, long id) {
		Intent result = new Intent();
		result.putExtra("routeid", id);
		setResult(Constants.SHOW_ROUTE, result);
		finish();
	}

	@Override
	public boolean onMenuItemSelected(int featureId, MenuItem item) {
		switch (item.getItemId()) {
		case Constants.MENU_SHOW: {
			onListItemClick(null, null, 0, routeId);
			return true;
		}
		case Constants.MENU_EDIT: {
			Intent intent = new Intent(this, RouteDetails.class);
			intent.putExtra("routeid", routeId);
			startActivity(intent);
			return true;
		}
		case Constants.MENU_DELETE: {
			Intent intent = new Intent(Intent.ACTION_DELETE);
			Uri uri = ContentUris.withAppendedId(RoutesColumns.CONTENT_URI,
					routeId);
			intent.setDataAndType(uri, RoutesColumns.CONTENT_ITEMTYPE);
			startActivity(intent);
			return true;
		}
		default:
			Log.w(TAG,
					"Unknown menu item: " + item.getItemId() + "("
							+ item.getTitle() + ")");
			return super.onMenuItemSelected(featureId, item);
		}
	}

	@Override
	public void onClick(View v) {
		switch (v.getId()) {
		case R.id.routelist_btn_delete_all: {
			Handler h = new DeleteAllRoutes(this, null);
			h.handleMessage(null);
			break;
		}

		}
	}

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		// We don't need a window title bar:
		requestWindowFeature(Window.FEATURE_NO_TITLE);

		setContentView(R.layout.myroutes_list);

		listView = getListView();
		listView.setOnCreateContextMenuListener(contextMenuListener);

		preferences = getSharedPreferences(Constants.SETTINGS_NAME,
				Context.MODE_PRIVATE);
		serviceConnection = new ConnectionServiceManager(this,
				serviceBindingChanged);

		View deleteAll = findViewById(R.id.routelist_btn_delete_all);
		deleteAll.setOnClickListener(this);

		updateButtonsEnabled();

		preferences.registerOnSharedPreferenceChangeListener(this);
		metricUnits = preferences.getBoolean(
				getString(R.string.metric_units_key), true);
		recordingRouteId = preferences.getLong(
				getString(R.string.recording_route_key), -1);

		routesCursor = getContentResolver().query(RoutesColumns.CONTENT_URI,
				null, null, null, "_id DESC");
		startManagingCursor(routesCursor);
		setListAdapter();
	}

	@Override
	protected void onStart() {
		super.onStart();

		serviceConnection.bindServiceIfRunning();
	}

	@Override
	protected void onDestroy() {
		serviceConnection.unbind();

		super.onDestroy();
	}

	private void updateButtonsEnabled() {
		View deleteAll = findViewById(R.id.routelist_btn_delete_all);
		//View exportAll = findViewById(R.id.routelist_btn_export_all);

		boolean notRecording = !isRecording();
		deleteAll.setEnabled(notRecording);
		//exportAll.setEnabled(notRecording);
	}

	private void setListAdapter() {
		// Get a cursor with all routes
		SimpleCursorAdapter adapter = new SimpleCursorAdapter(this,
				R.layout.myroutes_list_item, routesCursor, new String[] {
						RoutesColumns.NAME, RoutesColumns.START_TIME,
						RoutesColumns.TOTAL_DISTANCE,
						RoutesColumns.DESCRIPTION, RoutesColumns.CATEGORY },
				new int[] { R.id.routedetails_item_name,
						R.id.routedetails_item_time,
						R.id.routedetails_item_stats,
						R.id.routedetails_item_description,
						R.id.routedetails_item_category });

		final int startTimeIdx = routesCursor
				.getColumnIndexOrThrow(RoutesColumns.START_TIME);
		final int totalTimeIdx = routesCursor
				.getColumnIndexOrThrow(RoutesColumns.TOTAL_TIME);
		final int totalDistanceIdx = routesCursor
				.getColumnIndexOrThrow(RoutesColumns.TOTAL_DISTANCE);

		adapter.setViewBinder(new SimpleCursorAdapter.ViewBinder() {
			@Override
			public boolean setViewValue(View view, Cursor cursor,
					int columnIndex) {
				TextView textView = (TextView) view;
				if (columnIndex == startTimeIdx) {
					long time = cursor.getLong(startTimeIdx);
					textView.setText(String.format("%tc", time));
				} else if (columnIndex == totalDistanceIdx) {
					double length = cursor.getDouble(totalDistanceIdx);
					String lengthUnit = null;
					if (metricUnits) {
						if (length > 1000) {
							length /= 1000;
							lengthUnit = getString(R.string.unit_kilometer);
						} else {
							lengthUnit = getString(R.string.unit_meter);
						}
					} else {
						if (length > UnitConversions.MI_TO_M) {
							length /= UnitConversions.MI_TO_M;
							lengthUnit = getString(R.string.unit_mile);
						} else {
							length *= UnitConversions.M_TO_FT;
							lengthUnit = getString(R.string.unit_feet);
						}
					}
					textView.setText(String
							.format("%s  %.2f %s", StringsProfiler
									.formatTime(cursor.getLong(totalTimeIdx)),
									length, lengthUnit));
				} else {
					textView.setText(cursor.getString(columnIndex));
					if (textView.getText().length() < 1) {
						textView.setVisibility(View.GONE);
					} else {
						textView.setVisibility(View.VISIBLE);
					}
				}
				return true;
			}
		});
		setListAdapter(adapter);
	}

	private boolean isRecording() {
		return ServiceControl.isRecording(RouteList.this,
				serviceConnection.getServiceIfBound(), preferences);
	}
}